package com.wang.cloud.manage.service.manage;

import com.wang.cloud.common.core.exception.ServiceException;
import com.wang.cloud.manage.convert.RoleConvertor;
import com.wang.cloud.manage.domain.co.IdCo;
import com.wang.cloud.manage.domain.co.RoleAddCo;
import com.wang.cloud.manage.domain.co.RoleUpdateCo;
import com.wang.cloud.manage.domain.co.UpdateStatusCo;
import com.wang.cloud.manage.domain.entity.RoleEntity;
import com.wang.cloud.manage.domain.vo.MenuTreeVo;
import com.wang.cloud.manage.domain.vo.RoleDetailVo;
import com.wang.cloud.manage.domain.vo.RoleMenuIdsVo;
import com.wang.cloud.manage.service.IMenuService;
import com.wang.cloud.manage.service.IRoleMenuRelationService;
import com.wang.cloud.manage.service.IRoleService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * @author wangye
 * @date 2023/8/10 0010
 */
@Slf4j
@Service
public class RoleManageService {

    @Resource
    private IRoleService roleService;
    @Resource
    private IMenuService menuService;
    @Resource
    private IRoleMenuRelationService roleMenuRelationService;

    @Resource
    private RoleConvertor roleConvertor;


    public RoleDetailVo queryInfo(Long roleId) {
        RoleEntity entity = roleService.getById(roleId);
        if (Objects.isNull(entity)) {
            throw new ServiceException("角色不存在或已删除");
        }
        List<Long> menuIds = roleMenuRelationService.queryMenuIdsByRoleId(entity.getId());
        RoleDetailVo vo = roleConvertor.entityToDetailVo(entity);
        vo.setMenuIds(menuIds);
        return vo;
    }

    public List<MenuTreeVo> getMenuTree(Long roleId) {
        RoleEntity entity = roleService.getById(roleId);
        if (Objects.isNull(entity)) {
            throw new ServiceException("角色不存在或已删除");
        }
        List<Long> menuIds = roleMenuRelationService.queryMenuIdsByRoleId(roleId);
        if (menuIds.isEmpty()) {
            return Collections.emptyList();
        }
        return menuService.getTree(null, menuIds);
    }

    public RoleMenuIdsVo getMenuIds(Long roleId) {
        RoleEntity entity = roleService.getById(roleId);
        if (Objects.isNull(entity)) {
            throw new ServiceException("角色不存在或已删除");
        }
        return roleMenuRelationService.queryMenuIdsVoByRoleId(roleId);
    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean addRole(RoleAddCo co) {
        if (roleService.nameIsRepeat(null, co.getRoleName())) {
            throw new ServiceException("角色名称已存在");
        }
        if (Objects.equals(co.getRoleKey(), DEFAULT_ROLE_KEY)) {
            throw new ServiceException("禁止使用超级管理员的权限字符串");
        }
        if (!menuService.allExists(co.getFullMenuIds())) {
            throw new ServiceException("存在非法的路由信息！请确认路由未删除");
        }
        if (!menuService.allExists(co.getHalfMenuIds())) {
            throw new ServiceException("存在非法的路由信息！请确认路由未删除");
        }
        RoleEntity newInfo = roleConvertor.addCoToEntity(co);
        roleService.save(newInfo);

        roleMenuRelationService.saveRoleMenus(newInfo.getId(), co.getFullMenuIds(), co.getHalfMenuIds());
        return Boolean.TRUE;
    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean updateRole(RoleUpdateCo co) {
        RoleEntity oldInfo = getAndCheckId(co.getId());
        if (roleService.nameIsRepeat(oldInfo.getId(), co.getRoleName())) {
            throw new ServiceException("角色名称已存在");
        }
        if (Objects.equals(oldInfo.getRoleKey(), DEFAULT_ROLE_KEY)
                && !Objects.equals(co.getRoleKey(), DEFAULT_ROLE_KEY)) {
            throw new ServiceException("禁止修改该角色的权限字符串");
        }
        // 角色权限字符串变动后，不能是超级管理员的默认权限字符串
        if (!Objects.equals(oldInfo.getRoleKey(), co.getRoleKey())
                && Objects.equals(co.getRoleKey(), DEFAULT_ROLE_KEY)) {
            throw new ServiceException("禁止使用超级管理员的权限字符串");
        }
        if (!menuService.allExists(co.getFullMenuIds())) {
            throw new ServiceException("存在非法的路由信息！请确认路由未删除");
        }
        if (!menuService.allExists(co.getHalfMenuIds())) {
            throw new ServiceException("存在非法的路由信息！请确认路由未删除");
        }

        RoleEntity newInfo = roleConvertor.updateCoToEntity(co);
        roleService.updateById(newInfo);

        roleMenuRelationService.saveRoleMenus(newInfo.getId(), co.getFullMenuIds(), co.getHalfMenuIds());
        return Boolean.TRUE;
    }

    private RoleEntity getAndCheckId(Long roleId) {
        RoleEntity oldInfo = roleService.getById(roleId);
        if (Objects.isNull(oldInfo)) {
            throw new ServiceException("角色不存在或已删除");
        }
        return oldInfo;
    }

    private static final String DEFAULT_ROLE_KEY = "superAdmin";


    @Transactional(rollbackFor = Exception.class)
    public void updateRoleStatus(UpdateStatusCo co) {
        getAndCheckId(co.getId());
        RoleEntity entity = new RoleEntity();
        entity.setId(co.getId());
        entity.setStatus(co.getStatus());
        roleService.updateById(entity);
    }


    @Transactional(rollbackFor = Exception.class)
    public Boolean delRole(IdCo co) {
        RoleEntity oldInfo = roleService.getById(co.getId());
        if (Objects.isNull(oldInfo)) {
            return Boolean.FALSE;
        }
        if (Objects.equals(oldInfo.getRoleKey(), DEFAULT_ROLE_KEY)) {
            throw new ServiceException("禁止删除该角色");
        }
        return delRole(co.getId());
    }


    @Transactional(rollbackFor = Exception.class)
    public Boolean delRole(Long roleId) {
        // 删除角色
        boolean result = roleService.del(roleId);
        //  删除 角色-菜单关系
        roleMenuRelationService.delByRoleId(roleId);
        //  TODO 删除 人员-角色关系
//        roleRelationService.delByRoleId(roleId);
        return result;
    }
}
